package com.weight.data;

import java.text.DateFormat;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteStatement;

import com.weight.AppWeight;
import com.weight.data.model.Log;
import com.weight.util.Constants;
import com.weight.util.Utilities;

public class DataBaseHelper extends SQLiteOpenHelper {

	/**
	 * Database name
	 */
	private static final String DATABASE_NAME = "Weight_database";

	private DataBaseHelper(Context context, int version) {
		super(context, DATABASE_NAME, null, version);
	}

	private static DataBaseHelper _instance;

	public static DataBaseHelper getInstance() {
		if (_instance == null) {
			_instance = new DataBaseHelper(AppWeight.getInstance()
					.getApplicationContext(), 1);
		}
		return _instance;
	}

	/**
	 * Log Table is created
	 */
	@Override
	public void onCreate(SQLiteDatabase db) {
		if (db != null) {
			db.execSQL(Constants.WEIGTH_TABLE_CREATE);

		}

	}

	@Override
	public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
		// TODO Auto-generated method stub

	}

	/**
	 * Method that inserts a log in the registry log table
	 * 
	 * @param calendar
	 * @param weight
	 */
	public void addWeightLog(Log log) {
		Calendar calendar = log.getDate();
		float weight = log.getWeight();
		SQLiteDatabase db = getWritableDatabase();

		ContentValues cv = new ContentValues();
		cv.put(Constants.WEIGHT_TABLE_DATE_COLUMN, DateFormat.getDateInstance()
				.format(calendar.getTime()));

		cv.put(Constants.WEIGHT_TABLE_WEIGHT_COLUMN, weight);

		db.insert(Constants.WEIGHT_TABLE, null, cv);
	}

	/**
	 * Gets the cursor of all the Registry
	 * @param weightKilograms 
	 * 
	 * @return the ordered cursor
	 */
	public Cursor getCursor(boolean weightKilograms) {
		SQLiteDatabase db = getReadableDatabase();
		Cursor cursor = null;
		if (db != null) {
			String query = "SELECT  _id," + Constants.WEIGHT_TABLE_DATE_COLUMN
					+ "," + Constants.WEIGHT_TABLE_WEIGHT_COLUMN + " FROM "
					+ Constants.WEIGHT_TABLE;
			cursor = db.rawQuery(query, null);
		}
		Cursor ordered = orderCursor(cursor,weightKilograms);
		return ordered;
	}

	private Cursor orderCursor(Cursor cursor, boolean weightKilograms) {
		OrderedCursor ordered = new OrderedCursor();
		SortedSet<Log> set = new TreeSet<Log>(new Comparator<Log>(){

			@Override
			public int compare(Log arg0, Log arg1) {
				int result = 0;
				if(arg0.getDate().after(arg1.getDate())){
					result = 1;
				} else {
					result = -1;
					
				}
				return result;
			}

			
		});

		if (cursor != null && cursor.moveToFirst()) {
			while (!cursor.isAfterLast()) {
				Log log = getLogFromCursor(cursor,weightKilograms);
                set.add(log);
			cursor.moveToNext();
			}
		}
		
		Iterator<Log> it = set.iterator();
		while(it.hasNext()) {
			ordered.addLog(it.next());
		}
		return ordered;
	}

	/**
	 * Constructs a log from a cursor
	 * 
	 * @param cursor
	 * @param weightKilograms 
	 * @return The log of the current row
	 */
	private Log getLogFromCursor(Cursor cursor, boolean weightKilograms) {
		Log log = null;
		try {
			float weigth = cursor.getFloat(cursor
					.getColumnIndex(Constants.WEIGHT_TABLE_WEIGHT_COLUMN)); 
			if(!weightKilograms) {
				weigth = Utilities.kiloToPounds(weigth);
			}
			String dateString = cursor.getString(cursor
					.getColumnIndex(Constants.WEIGHT_TABLE_DATE_COLUMN));
			int _id = cursor.getInt(cursor
					.getColumnIndex("_id"));
			Date date = DateFormat.getDateInstance().parse(dateString);
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(date);
			log = new Log(calendar, weigth);
			log.set_id(_id);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return log;
	}

	public void updateWeightLog(int position, Log log) {
		SQLiteDatabase db = getWritableDatabase();
		String statement = "update " + Constants.WEIGHT_TABLE + " set "
				+ Constants.WEIGHT_TABLE_DATE_COLUMN + "= ? , "
				+ Constants.WEIGHT_TABLE_WEIGHT_COLUMN + "=? WHERE _id = ?";
		SQLiteStatement stmt = db.compileStatement(statement);
		stmt.bindString(1, DateFormat.getDateInstance().format(
				log.getDate().getTime()));
		stmt.bindString(2, "" + log.getWeight());
		stmt.bindLong(3, position);
		if (db != null) {
			stmt.execute();
		}

	}

	public Cursor getLog(int position) {
		SQLiteDatabase db = getReadableDatabase();
		Cursor cursor = null;
		if (db != null) {
			String query = "SELECT  _id," + Constants.WEIGHT_TABLE_DATE_COLUMN
					+ "," + Constants.WEIGHT_TABLE_WEIGHT_COLUMN + " FROM "
					+ Constants.WEIGHT_TABLE + " where _id=" + position;
			cursor = db.rawQuery(query, null);
		}
		return cursor;
	}

	/**
	 * Cursor used for the search feature.
	 */
	private static class OrderedCursor extends MatrixCursor {
		private static final String[] COLUMNS = {
				Constants.WEIGHT_TABLE_DATE_COLUMN,
				Constants.WEIGHT_TABLE_WEIGHT_COLUMN, "_id" };

		public OrderedCursor() {
			super(COLUMNS);
		}

		public void addLog(Log log) {
			addRow(new Object[] { DateFormat.getDateInstance()
					.format(log.getDate().getTime()) , log.getWeight(), log.get_id() });
		}
	}

}
